分享好友 技术首页 技术分类 切换频道

嵌入式Linux下的USB设备驱动技术

2020-07-19 22:11130

前言:Linux以其稳定、、易定制、硬件支持广泛、源代码开放等特点,已在嵌入式领域迅速崛起,被国际上许多大型的跨国企业用作嵌入式产品的系统平台。

  USB是Universal Serial Bus (通用串行总线)的缩写,是1995年由Microsoft、Compaq、IBM等公司联合制定的一种新的PC串行通信协议。它是一种快速、灵活的总线接口。与其它通信接口相比较,USB接口的zui大特点是易于使用,这也是USB的主要设计目标。USB的成功得益于在USB标准中除定义了通信的物理层和电器层标准外。还定义了一套相对完整的软件协议堆栈。这使得多数USB设备都很容易在各种平台上工作。作为一种高速总线接口,USB适用于多种设备(如数码相机、MP3播放器、高速数据采集设备等)。另外,USB接口还支持热插拔,而且所有的配置过程都由系统自动完成,无须用户干预。

  1 Linux下的USB设备驱动

  在Linux内核的不断升级过程中,驱动程序的结构相对稳定。由于USB设备也是外围设备的一种,因此,它的驱动程序结构与普通设备的驱动程序相同。Linux系统的设备分为字符设备(CharDevice)和块设备(BlockDevice)。字符设备支持面向块字符的I/O操作,它不通过系统的快速缓存,而只支持顺序存取。块设备则支持面向块的I/O操作,所有块设备的I/O操作都通过在内核地址空间的I/O缓冲区进行,可以支持几乎任意长度和任意位置上的I/O请求。块设备与字符设备还有一点不同,就是块设备必须能够随机存取(RandomAccess),字符设备则没有这个要求。典型的字符设备包括鼠标、键盘、串行口等,而块设备主要包括硬盘软盘设备、CD-Rom等。由于USB设备主要都是通过快速串行通讯来读写数据,因此一般都可作为字符设备来进行处理。

  2 Linux下的USB core

  2.1 Linux中USB core与USB的结构关系

  Linux操作系统中有一个叫做“USB core”的子系统,可提供支持USB设备驱动程序的API和USB主机控制器的驱动程序。同时提供有许多数据结构、宏定义和功能函数来对硬件或设备进行支持。在Linux下编写USB设备的驱动程序时,从严格意义上讲,就是使用这些USB core的子系统所定义的数据结构、宏和函数来编写数据的处理功能。在Linux下,core、host controller和driver三者之间的关系如图1所示。


  2.2 USB core的初始化

  USB core从USB子系统的初始化开始。USB子系统的初始化则在文件drivers/usb/core/usb.c里。其代码如下:

  subsys_initcall(usb_init);
  module_exit(usb_exit);

  代码中的subsys_initcall是一个宏,相当于module_init,只不过因为这部分代码是核心,通常把它看作一个子系统,而不仅仅是一个模块。因为USB core模块代表的不是某一个设备,而是所有USB设备赖以生存的模块。因此,在Linux中,像这样把一个类别的设备驱动归结为一个子系统(比如PCI子系统、scsi子系统等)。基本上,drivers/目录下面*层的每个目录都可算作一个子系统,因为它们代表了一类设备。一般地,usb_init是真正的初始化函数,而usb_exit()则是整个USB子系统结束时的清理函数:


  函数usb_init主要完成初始化和注册设备。

  2.3 USB里的设备模型

  Linux里一个很重要的概念是设备模型。对于驱动来说,设备的概念就是总线和与其相连的各种设备。在内核里,总线、设备、驱动也就是bus、device、driver是设备模型很重要的三个概念,它们都有自己专属的结构。在include/linux/devide.h里的定义为:

  struct bus_type {……};
  struct device {……);
  struct device_driver {……};

  每次出现一个设备都要向总线注册,每次出现一个驱动,也要向总线注册。系统初始化时,应扫描连接许多设备,并为每一个设备建立一个struct device的变量。每一次都应有一个驱动程序,并要准备一个struct device_driver结构的变量。还要把这些变量加入相应的链表(如把device插入devices链表,driver插入drivers链表)。这样,通过总线就能找到每一个设备和每一个驱动。然而,假如计算机里只有设备却没有对应的驱动,那么设备将无法工作。反过来,倘若只有驱动却没有设备,驱动也起不了任何作用。对于USB设备,它可以在计算机启动以后再插入或者拔出计算机。由于device可以在任何时刻出现,而driver也可以在任何时刻被加载,所以,每当一个struct device诞生时,它就会去BUS的drivers链表中寻找自己的另一半。如果找到了匹配的设备,就调用device_bind_driver,并绑定好。

  Linux设备模型中的总线落实在USB子系统里就是usb_bus_type,它在usb_init函数中可用retval=bus_register(&usb_bus_type)语句注册,而在driver.c文件里的定义如下:
 

  该函数的形参对应的就是总线两条链表里的设备和驱动。当总线上有新设备和驱动时,这个函数就会被调用。

  3 USB驱动程序的描述符

  一个设备可以有多个接口,一个接口可代表一个功能,因此,每个接口都对应着一个驱动。例如一个USB设备有两种功能,一个键盘,上面还带一个扬声器,这就是两个接口,就需要两个驱动程序,一个是键盘驱动程序,一个是音频流驱动程序。

  一个驱动程序是否支持一个设备,要通过读取设备的描述符来判断。那么,什么是USB的描述符呢?USB的描述符是一个带有预定义格式的数据结构,里面保存有USB设备的各种属性和相关信息,可以通过向设备请求获得它们的描述符内容来深刻了解和感知一个USB设备。主要有四种USB描述符,分别为:接口描述符、端点描述符、设备描述符和配置描述符。

  协议规定:一个USB设备必须支持这四大描述符,还有些描述符不是必须包含的,有些特殊设备用来描述设备的不同特性,但这四大描述符是一个都不能少的。USB设备里有一个eeprom,可用来存储设备本身信息,设备的描述符就存储在这里。

  上述四个描述符分别放在了include/linux/usb.h文件中的struct usb_host_interface、structusb_host_endpoint、struct usb_device、struetusb_host_config里,而描述符结构体本身定义在include/linux/usb/ch9.h里.并分别用struct usb_interface_descriptor、struct usb_host_endpoint、structusb_device_descriptor和struct usb_config_descriptor来表示。描述符结构体的定义应完全按照USB协议对描述符的规定来定义。

  4 USB接口驱动

  4.1 接口结构

  平时编写的USB驱动通常指的是写USB接口的驱动,一个接口对应一个接口驱动程序,需要以一个struct usb_driver结构的对象为中心,并以设备的接口提供的功能为基础,来进行USB驱动程序的编写。struct usb_driver结构体一般定义在include/linux/usb.h文件里。具体如下:

  struct usb_driver{
  const char*name;
  int(*probe) (struct usb_interface*intf,const
  struct usb_device_jd*id);
  void(*disconnect) (struct usb_interface*intf);
  int(*ioctl) (struct usb_interface*intf,unsigned
  int code,void*buf);
  int (*suspend) (struct usb_interface*intf,
  pm_message_t message);
  int(*resume) (struct usb_interface*intf);
  void(*pre_reset) (struct usb_interface*intf);
  void(*post_reset)(struct usb_interface*intf);
  const struct usb_device_id*id_table;
  struct usb_dynids dynids;
  struct usbdrv_wrap drvwrap;
  unsigned int no_dynamic_id:1;
  unsigned int supports_autosuspend:1;
  };

  Name为驱动程序的名字,对应于/sys/bus/usb/drivers/下面的子目录名称。它只是彼此区别的一个代号,这里的名字在所有的USB驱动中必须是*的。probe用来看看这个USB驱动是否愿意接受某个接口的函数。Disconnect函数将在接口失去或使用rmmod卸载驱动将它和接口强行分开时被调用。Ioctl函数则用在驱动通过usbfs和用户空间进行交流时使用。Suspend、esume分别在设备被挂起和唤醒时使用。pre_reset、post_reset分别在设备将要复位(reset)和已经复位后使用。id_table的变量可用来判断是否支持某个设备接口。Dynids是支持动态id的。实际上,即使驱动已经加载了,也可以添加新的id给它。drvwrap是给USB core区分设备驱动和接口驱动用的。no_dynamic_id可以用来禁止动态id。supports_autosuspend可对autosuspend提供支持,如果设置为0,则不再允许绑定到这个驱动的接口autosuspend。

  当insmod或modprobe驱动的时候,经过一个曲折的过程,就会调用相应USB驱动里的xxx_init函数,进而去调用usb_register (),以将相应的USB驱动提交给设备模型,添加到USB总线的驱动链表里。当rmmod驱动时,同样,在经过一个曲折的过程之后,再调用相应驱动里的xxx_cleanup函数,进而调用usb_deregister ()将相应的USB驱动从USB总线的驱动链表里删除。

  5 结束语

  本文介绍了Linux下USB core的工作原理,同时介绍了驱动USB必须了解的四个描述符。此外,还介绍了Linux下usb接口驱动的工作原理。本文介绍的方法能适应于Linux下各种不同的USB设备驱动程序的开发。

免责声明:矿库网文章内容来源于网络,为了传递信息,我们转载部分内容,尊重原作者的版权。所有转载文章仅用于学习和交流之目的,并非商业用途。如有侵权,请及时联系我们删除。感谢您的理解与支持。

点赞 0
举报
收藏 0
评论 0
分享 1
CP5611卡(6GK1561-1AA00和6GK1561-1AA01)和西门子总线连接器6ES7972-0BA12-0XA0,6ES7972-0BB12-0XA0,6ES7972-0
本公司经营西门子 CP5611卡 PLC,质量保证,洽谈。:肖锋: 工作CP5611卡简单介绍1、实现PC(计算机)与SIMATIC S7之间的PROFIBUS/MPI通讯连接; 2、CP5611可支持以下软件: STEP7V.52及以上 SOFTNET-S7 SOFTNET-DP SOFTNET-DP从站 COM P

0评论2020-07-20383

专营希捷SCSI硬盘、SAS硬盘、SATA硬盘、FC接口硬盘 13901101075
专营希捷SCSI接口、SAS接口、SATA接口、FC接口硬盘 一、希捷SCSI接口50针硬盘:ST34371N、ST34520N、ST32272N、ST32430N、ST318416N、ST31230N、ST39140N、ST32171N、ST34571N、ST34573N、ST39173N、ST39216N、ST318418N、ST336918N、ST3

0评论2020-07-20677

希捷ST9300603SS、ST9146852SS、ST9146802SS、ST973402SS SAS硬盘13901101075
北京双汇通公司销售大量SAS各种容量硬盘—— SAS即串行连接SCSI,是新一代的SCSI技术,和现在流行的Serial ATA(SATA)硬盘相同,都是采用串行技术以获得更高的传输速度,并通过缩短连结线改善内部空间等。SAS是并行SCSI接口之后开发出的

0评论2020-07-20629

智能液晶触摸显示终端与单片机接口的设计
题记:作为一种常见的显示设备,LCD具有功耗低,体积小,重量轻,显示信息量大等特点,尤其是在便携设备中,更占据着主流的地位。对于字符或数字的简单信息显示,通常可用段码式LCD驱动器。对于复杂的信息显示,则必须由点阵式LCD驱动器

0评论2020-07-20659

仿真测试软件 Kvaser CanKing
仿真测试软件 Kvaser CanKing Kvaser CanKing是一个免费的CAN总线监测器和通用诊断工具。 它特别适合于交互式开发工作。您可以容易地发送CAN消息并研究它们在目标模块上的影响。你只需要一个Kvaser CAN接口。 Kvaser CanKing完全免费。特

0评论2020-07-2085

智维 PCIEcan
智维 PCIEcan双通道高速 PCIX 接口 CAN 总线分析仪Kvaser PCIEcan 产品是高速 PCIX 接口 CAN 总线分析仪,该产品可无损耗的发送、接收 CAN 总线标准帧和扩展帧。硬件特点完全兼容高速PCI-X规范。 专为标准工业PC机设计。 安装快速、简易

0评论2020-07-20650

YC6990无线真彩触摸屏中控
一、系统概述YC6990控制系统是易控科技历经三年来研发出来一款在技术水平上可与国际先进品牌相抗衡的可编程中央控制系统,其强大的控制能力可以将不同厂家、型号及性质的视听器材或硬件,甚至环境装置连接起来。通过配合无线触摸屏EC57CW

0评论2020-07-20287

投影机开关集中控制解决方案
该解决方案采用我公司先进的YC6980可编程中控主机,ARM32位内嵌式处理器,高速运算处理,性能稳定,支持第三方设备及控制协议;系统自带红外仿真学习红能,16进制数据存储,方便系统维护和升级,8路独立可编程RS-232控制接口,可以收发RS

0评论2020-07-20109

智维 Memorator Professional
智维 MemoratorProfessional基于USB的实时CAN总线智能数据记录仪Kvaser Memorator Professional 是一款具有数据记录功能的 USB 接口 CAN 总线分析仪,该产品既可以用作 USB 接口的 CAN 总线分析仪(如 Kvaser USBcan Professional 分析仪

0评论2020-07-20373